#ifndef __MY_LIST_H__
#define __MY_LIST_H__

#include <assert.h>
#include <time.h>
#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif

#ifndef container_of
#define container_of(ptr, type, member) ({ typeof(((type *)0)->member) *__mptr = (ptr); (type *)((char *)__mptr - offsetof(type,member));})
#endif

#ifdef DBG_LIST
#define __LIST_HEAD_INIT_DBG(name) .item_count = 0, .__head = &(name), 
#else
#define __LIST_HEAD_INIT_DBG(name)
#endif
#define LIST_HEAD_INIT(name) { .next = &(name), .prev = &(name), __LIST_HEAD_INIT_DBG(name) }
#define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name)

#define IN_LIST_TAG 0x12569047
struct list_head {
	struct list_head *next, *prev;
    uint32_t is_in_list_tag;
#ifdef DBG_LIST
    int item_count;
    struct list_head *__head;
#endif
};

struct hlist_head {
	struct hlist_node *first;
#ifdef DBG_LIST
    uint32_t list_len;
#endif
};

struct hlist_node {
	struct hlist_node *next, **pprev;
#ifdef DBG_LIST
    struct hlist_head *my_hlist_head_at;
#endif
};

static inline void INIT_LIST_HEAD(struct list_head *list) { list->next = list; list->prev = list; list->is_in_list_tag = 0;
#ifdef DBG_LIST
    list->item_count = 0;
    list->__head = list;
#endif
}

#ifndef LOGFEW
#warning "LOGFEW should define before"
#define LOGFEW(fmt, ...) do { \
    static time_t last_ts = 0; time_t curr_ts = time(NULL); if (((unsigned)(curr_ts - last_ts)) >= 10) { last_ts = curr_ts; printf("%-20s %-20s() %-4d "fmt, __FILE__, __func__, __LINE__, ##__VA_ARGS__); } } while(0)
#endif
#define __list_add(new_entry, prev_entry, next_entry) do { \
    struct list_head *_new_entry = new_entry, *_prev_entry = prev_entry, *_next_entry = next_entry; \
    if (_new_entry->prev || _new_entry->next) LOGFEW("new_entry->prev %p new_entry->next %p should all be NULL!!\n", _new_entry->prev, _new_entry->next); \
	_next_entry->prev = _new_entry; \
	_new_entry->next = _next_entry; \
	_new_entry->prev = _prev_entry; \
	_prev_entry->next = _new_entry; \
    _new_entry->is_in_list_tag = IN_LIST_TAG; \
} while(0)

#define is_in_list(node) ((node)->is_in_list_tag == IN_LIST_TAG)
#define __lineval_name(line) lineval_##line
#define _lineval_name(line) __lineval_name(line)
#define lineval() _lineval_name(__LINE__)
#ifdef DBG_LIST
static inline void __check_list(int list_size, int *found_count, int inc, const char *func, int lineno) { if (inc) { *found_count += 1; if (*found_count > list_size) { printf("list_size %d, but found %d at func %s line %d\n", list_size, *found_count, func, lineno); abort(); } } }
#define list_for_each(pos, head) int lineval() = 0; for (pos = (head)->next; __check_list((head)->item_count, &lineval(), (pos != (head)), __func__, __LINE__), (pos != (head)); pos = pos->next)
#define list_for_each_entry(pos, head, member) int lineval() = 0; for (pos = list_first_entry(head, typeof(*pos), member); __check_list((head)->item_count, &lineval(), (&pos->member != (head)), __func__, __LINE__), (&pos->member != (head)); pos = list_next_entry(pos, member))
#else
#define list_for_each(pos, head) for (pos = (head)->next; pos != (head); pos = pos->next)
#define list_for_each_entry(pos, head, member) for (pos = list_first_entry(head, typeof(*pos), member); &pos->member != (head); pos = list_next_entry(pos, member))
#endif
#ifdef DBG_LIST
#define list_add_head(new_entry, head)              do { __list_add(new_entry, head, (head)->next); (head)->item_count++; (new_entry)->__head = head; struct list_head *_pos; int _item_count = 0; list_for_each(_pos, head) { _item_count++; assert(_item_count <= (head)->item_count); } assert((head)->item_count == _item_count); } while(0)
#define list_add_after(new_entry, old_entry, head)  do { __list_add(new_entry, old_entry, (old_entry)->next); (head)->item_count++; (new_entry)->__head = head; struct list_head *_pos; int _item_count = 0; list_for_each(_pos, head) { _item_count++; assert(_item_count <= (head)->item_count); } assert((head)->item_count == _item_count); } while(0)
#define list_add_tail(new_entry, head)              do { __list_add(new_entry, (head)->prev, head); (head)->item_count++; (new_entry)->__head = head; struct list_head *_pos; int _item_count = 0; list_for_each(_pos, head) { _item_count++; assert(_item_count <= (head)->item_count); } assert((head)->item_count == _item_count); } while(0)
#define list_add_before(new_entry, old_entry, head) do { __list_add(new_entry, (old_entry)->prev, old_entry); (head)->item_count++; (new_entry)->__head = head; struct list_head *_pos; int _item_count = 0; list_for_each(_pos, head) { _item_count++; assert(_item_count <= (head)->item_count); } assert((head)->item_count == _item_count); } while(0)
#else
#define list_add_head(new_entry, head)              do { __list_add(new_entry, head, (head)->next); } while(0)
#define list_add_tail(new_entry, head)              do { __list_add(new_entry, (head)->prev, head); } while(0)
#define list_add_after(new_entry, old_entry, head)  do { __list_add(new_entry, old_entry, (old_entry)->next); } while(0)
#define list_add_before(new_entry, old_entry, head) do { __list_add(new_entry, (old_entry)->prev, old_entry); } while(0)
#endif
static inline void __list_del(struct list_head * prev, struct list_head * next) { next->prev = prev; prev->next = next; }
#ifdef DBG_LIST
#define _list_item_count_dec(l) (l)->__head->item_count--
#else
#define _list_item_count_dec(l)
#endif
#define list_del(entry) do { \
    if ((entry) == NULL) { printf("%s %s() line %d entry is NULL, can not do list_del!!\n", __FILE__, __func__, __LINE__); abort(); } \
    if ((entry)->next == NULL || (entry)->prev == NULL) { printf("%s %s() line %d entry->next %p entry->prev %p, can not do list_del!!\n", __FILE__, __func__, __LINE__, (entry)->next, (entry)->prev); exit(1); }\
    __list_del((entry)->prev, (entry)->next); (entry)->next = NULL; (entry)->prev = NULL; (entry)->is_in_list_tag = 0; \
    _list_item_count_dec(entry); \
} while(0)
static inline void list_replace(struct list_head *old, struct list_head *new_entry) { new_entry->next = old->next; new_entry->next->prev = new_entry; new_entry->prev = old->prev; new_entry->prev->next = new_entry; }
static inline void list_replace_init(struct list_head *old, struct list_head *new_entry) { list_replace(old, new_entry); INIT_LIST_HEAD(old); }
static inline void list_move(struct list_head *entry, struct list_head *head) { __list_del(entry->prev, entry->next); (entry)->next = NULL; (entry)->prev = NULL; (entry)->is_in_list_tag = 0; list_add_head(entry, head); }
static inline void list_move_tail(struct list_head *entry, struct list_head *head) { __list_del(entry->prev, entry->next); (entry)->next = NULL; (entry)->prev = NULL; (entry)->is_in_list_tag = 0; list_add_tail(entry, head); }
static inline int list_is_last(const struct list_head *list, const struct list_head *head) { return list->next == head; }
static inline int list_empty(const struct list_head *head) { return head->next == head; }

/**
 * list_empty_careful - tests whether a list is empty and not being modified
 * @head: the list to test
 *
 * Description:
 * tests whether a list is empty _and_ checks that no other CPU might be
 * in the process of modifying either member (next or prev)
 *
 * NOTE: using list_empty_careful() without synchronization
 * can only be safe if the only activity that can happen
 * to the list entry is list_del_init(). Eg. it cannot be used
 * if another CPU could re-list_add() it.
 */
static inline int list_empty_careful(const struct list_head *head)
{
	struct list_head *next = head->next;
	return (next == head) && (next == head->prev);
}

/**
 * list_rotate_left - rotate the list to the left
 * @head: the head of the list
 */
static inline void list_rotate_left(struct list_head *head)
{
	struct list_head *first;

	if (!list_empty(head)) {
		first = head->next;
		list_move_tail(first, head);
	}
}

/**
 * list_is_singular - tests whether a list has just one entry.
 * @head: the list to test.
 */
static inline int list_is_singular(const struct list_head *head)
{
	return !list_empty(head) && (head->next == head->prev);
}

static inline void __list_cut_position(struct list_head *list,
		struct list_head *head, struct list_head *entry)
{
	struct list_head *new_first = entry->next;
	list->next = head->next;
	list->next->prev = list;
	list->prev = entry;
	entry->next = list;
	head->next = new_first;
	new_first->prev = head;
}

/**
 * list_cut_position - cut a list into two
 * @list: a new_entry list to add all removed entries
 * @head: a list with entries
 * @entry: an entry within head, could be the head itself
 *	and if so we won't cut the list
 *
 * This helper moves the initial part of @head, up to and
 * including @entry, from @head to @list. You should
 * pass on @entry an element you know is on @head. @list
 * should be an empty list or a list you do not care about
 * losing its data.
 *
 */
static inline void list_cut_position(struct list_head *list,
		struct list_head *head, struct list_head *entry)
{
	if (list_empty(head))
		return;
	if (list_is_singular(head) &&
		(head->next != entry && head != entry))
		return;
	if (entry == head)
		INIT_LIST_HEAD(list);
	else
		__list_cut_position(list, head, entry);
}

static inline void __list_splice(const struct list_head *list, struct list_head *prev, struct list_head *next)
{
#ifdef DBG_LIST
    struct list_head *pos;
    list_for_each(pos, list) {
        pos->__head = next->__head;
        pos->__head->item_count++;
    }
    list->__head->item_count = 0;
#endif
	struct list_head *first = list->next;
	struct list_head *last = list->prev;

	first->prev = prev;
	prev->next = first;

	last->next = next;
	next->prev = last;
}

/**
 * list_splice - join two lists, this is designed for stacks
 * @list: the new_entry list to add.
 * @head: the place to add it in the first list.
 */
static inline void list_splice(const struct list_head *list, struct list_head *head)
{
	if (!list_empty(list)) __list_splice(list, head, head->next);
}

/**
 * list_splice_tail - join two lists, each list being a queue
 * @list: the new_entry list to add.
 * @head: the place to add it in the first list.
 */
static inline void list_splice_tail(struct list_head *list, struct list_head *head)
{
	if (!list_empty(list)) __list_splice(list, head->prev, head);
}

/**
 * list_splice_init - join two lists and reinitialise the emptied list.
 * @list: the new_entry list to add.
 * @head: the place to add it in the first list.
 *
 * The list at @list is reinitialised
 */
static inline void list_splice_init(struct list_head *list, struct list_head *head)
{
	if (!list_empty(list)) { __list_splice(list, head, head->next); INIT_LIST_HEAD(list); }
}

/**
 * list_splice_tail_init - join two lists and reinitialise the emptied list
 * @list: the new_entry list to add.
 * @head: the place to add it in the first list.
 *
 * Each of the lists is a queue.
 * The list at @list is reinitialised
 */
static inline void list_splice_tail_init(struct list_head *list, struct list_head *head)
{
	if (!list_empty(list)) { __list_splice(list, head->prev, head); INIT_LIST_HEAD(list); }
}

/**
 * list_entry - get the struct for this entry
 * @ptr:	the &struct list_head pointer.
 * @type:	the type of the struct this is embedded in.
 * @member:	the name of the list_head within the struct.
 */
#define list_entry(ptr, type, member) \
	container_of(ptr, type, member)

/**
 * list_first_entry - get the first element from a list
 * @ptr:	the list head to take the element from.
 * @type:	the type of the struct this is embedded in.
 * @member:	the name of the list_head within the struct.
 *
 * Note, that list is expected to be not empty.
 */
#define list_first_entry(ptr, type, member) \
	list_entry((ptr)->next, type, member)

/**
 * list_last_entry - get the last element from a list
 * @ptr:	the list head to take the element from.
 * @type:	the type of the struct this is embedded in.
 * @member:	the name of the list_head within the struct.
 *
 * Note, that list is expected to be not empty.
 */
#define list_last_entry(ptr, type, member) \
	list_entry((ptr)->prev, type, member)

/**
 * list_first_entry_or_null - get the first element from a list
 * @ptr:	the list head to take the element from.
 * @type:	the type of the struct this is embedded in.
 * @member:	the name of the list_head within the struct.
 *
 * Note that if the list is empty, it returns 0.
 */
#define list_first_entry_or_null(ptr, type, member) ({ \
	struct list_head *head__ = (ptr); \
	struct list_head *pos__ = head__->next; \
	pos__ != head__ ? list_entry(pos__, type, member) : 0; \
})

/**
 * list_next_entry - get the next element in list
 * @pos:	the type * to cursor
 * @member:	the name of the list_head within the struct.
 */
#define list_next_entry(pos, member) list_entry((pos)->member.next, typeof(*(pos)), member)

/**
 * list_prev_entry - get the prev element in list
 * @pos:	the type * to cursor
 * @member:	the name of the list_head within the struct.
 */
#define list_prev_entry(pos, member) \
	list_entry((pos)->member.prev, typeof(*(pos)), member)


/**
 * list_for_each_prev	-	iterate over a list backwards
 * @pos:	the &struct list_head to use as a loop cursor.
 * @head:	the head for your list.
 */
#define list_for_each_prev(pos, head) \
	for (pos = (head)->prev; pos != (head); pos = pos->prev)

/**
 * list_for_each_safe - iterate over a list safe against removal of list entry
 * @pos:	the &struct list_head to use as a loop cursor.
 * @n:		another &struct list_head to use as temporary storage
 * @head:	the head for your list.
 */
#define list_for_each_safe(pos, n, head) \
	for (pos = (head)->next, n = pos->next; pos != (head); \
		pos = n, n = pos->next)

/**
 * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
 * @pos:	the &struct list_head to use as a loop cursor.
 * @n:		another &struct list_head to use as temporary storage
 * @head:	the head for your list.
 */
#define list_for_each_prev_safe(pos, n, head) \
	for (pos = (head)->prev, n = pos->prev; \
	     pos != (head); \
	     pos = n, n = pos->prev)

/**
 * list_for_each_entry_reverse - iterate backwards over list of given type.
 * @pos:	the type * to use as a loop cursor.
 * @head:	the head for your list.
 * @member:	the name of the list_head within the struct.
 */
#define list_for_each_entry_reverse(pos, head, member)			\
	for (pos = list_last_entry(head, typeof(*pos), member);		\
	     &pos->member != (head); 					\
	     pos = list_prev_entry(pos, member))

/**
 * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
 * @pos:	the type * to use as a start point
 * @head:	the head of the list
 * @member:	the name of the list_head within the struct.
 *
 * Prepares a pos entry for use as a start point in list_for_each_entry_continue().
 */
#define list_prepare_entry(pos, head, member) ((pos) ? : list_entry(head, typeof(*pos), member))

/**
 * list_for_each_entry_continue - continue iteration over list of given type
 * @pos:	the type * to use as a loop cursor.
 * @head:	the head for your list.
 * @member:	the name of the list_head within the struct.
 *
 * Continue to iterate over list of given type, continuing after
 * the current position.
 */
#define list_for_each_entry_continue(pos, head, member) 		\
	for (pos = list_next_entry(pos, member);			\
	     &pos->member != (head);					\
	     pos = list_next_entry(pos, member))

/**
 * list_for_each_entry_continue_reverse - iterate backwards from the given point
 * @pos:	the type * to use as a loop cursor.
 * @head:	the head for your list.
 * @member:	the name of the list_head within the struct.
 *
 * Start to iterate over list of given type backwards, continuing after
 * the current position.
 */
#define list_for_each_entry_continue_reverse(pos, head, member)		\
	for (pos = list_prev_entry(pos, member);			\
	     &pos->member != (head);					\
	     pos = list_prev_entry(pos, member))

/**
 * list_for_each_entry_from - iterate over list of given type from the current point
 * @pos:	the type * to use as a loop cursor.
 * @head:	the head for your list.
 * @member:	the name of the list_head within the struct.
 *
 * Iterate over list of given type, continuing from current position.
 */
#define list_for_each_entry_from(pos, head, member) 			\
	for (; &pos->member != (head);					\
	     pos = list_next_entry(pos, member))

/**
 * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
 * @pos:	the type * to use as a loop cursor.
 * @n:		another type * to use as temporary storage
 * @head:	the head for your list.
 * @member:	the name of the list_head within the struct.
 */
#define list_for_each_entry_safe(pos, n, head, member)			\
	for (pos = list_first_entry(head, typeof(*pos), member),	\
		n = list_next_entry(pos, member);			\
	     &pos->member != (head); 					\
	     pos = n, n = list_next_entry(n, member))

/**
 * list_for_each_entry_safe_continue - continue list iteration safe against removal
 * @pos:	the type * to use as a loop cursor.
 * @n:		another type * to use as temporary storage
 * @head:	the head for your list.
 * @member:	the name of the list_head within the struct.
 *
 * Iterate over list of given type, continuing after current point,
 * safe against removal of list entry.
 */
#define list_for_each_entry_safe_continue(pos, n, head, member) 		\
	for (pos = list_next_entry(pos, member), 				\
		n = list_next_entry(pos, member);				\
	     &pos->member != (head);						\
	     pos = n, n = list_next_entry(n, member))

/**
 * list_for_each_entry_safe_from - iterate over list from current point safe against removal
 * @pos:	the type * to use as a loop cursor.
 * @n:		another type * to use as temporary storage
 * @head:	the head for your list.
 * @member:	the name of the list_head within the struct.
 *
 * Iterate over list of given type from current point, safe against
 * removal of list entry.
 */
#define list_for_each_entry_safe_from(pos, n, head, member) 			\
	for (n = list_next_entry(pos, member);					\
	     &pos->member != (head);						\
	     pos = n, n = list_next_entry(n, member))

/**
 * list_for_each_entry_safe_reverse - iterate backwards over list safe against removal
 * @pos:	the type * to use as a loop cursor.
 * @n:		another type * to use as temporary storage
 * @head:	the head for your list.
 * @member:	the name of the list_head within the struct.
 *
 * Iterate backwards over list of given type, safe against removal
 * of list entry.
 */
#define list_for_each_entry_safe_reverse(pos, n, head, member)		\
	for (pos = list_last_entry(head, typeof(*pos), member),		\
		n = list_prev_entry(pos, member);			\
	     &pos->member != (head); 					\
	     pos = n, n = list_prev_entry(n, member))

/**
 * list_safe_reset_next - reset a stale list_for_each_entry_safe loop
 * @pos:	the loop cursor used in the list_for_each_entry_safe loop
 * @n:		temporary storage used in list_for_each_entry_safe
 * @member:	the name of the list_head within the struct.
 *
 * list_safe_reset_next is not safe to use in general if the list may be
 * modified concurrently (eg. the lock is dropped in the loop body). An
 * exception to this is if the cursor element (pos) is pinned in the list,
 * and list_safe_reset_next is called after re-taking the lock and before
 * completing the current iteration of the loop body.
 */
#define list_safe_reset_next(pos, n, member) n = list_next_entry(pos, member)

/*
 * Double linked lists with a single pointer list head.
 * Mostly useful for hash tables where the two pointer list head is
 * too wasteful.
 * You lose the ability to access the tail in O(1).
 */

#define HLIST_HEAD_INIT { .first = 0 }
#define HLIST_HEAD(name) struct hlist_head name = {  .first = 0 }
#define INIT_HLIST_HEAD(ptr) ((ptr)->first = 0)
static inline void INIT_HLIST_NODE(struct hlist_node *h)
{
	h->next = 0;
	h->pprev = 0;
}

static inline int hlist_unhashed(const struct hlist_node *h)
{
	return !h->pprev;
}

static inline int hlist_empty(const struct hlist_head *h)
{
	return !h->first;
}

static inline void __hlist_del(struct hlist_node *n)
{
	struct hlist_node *next = n->next;
	struct hlist_node **pprev = n->pprev;

	*pprev = next;
	if (next) next->pprev = pprev;
#ifdef DBG_LIST
    n->my_hlist_head_at->list_len--;
#endif
}

#define hlist_del(hnode) \
    do { \
        if ((hnode) && (hnode)->pprev) { __hlist_del((hnode)); (hnode)->next = NULL; (hnode)->pprev = NULL; \
        } else if ((hnode) == NULL) { printf("%s %s() line %d hnode is NULL, can not do hlist_del!!\n", __FILE__, __func__, __LINE__); abort(); \
        } else { printf("%s %s() line %d hnode->pprev %p, can not do hlist_del!!\n", __FILE__, __func__, __LINE__, (hnode)->pprev); abort(); } \
    } while(0)

static inline void hlist_del_init(struct hlist_node *n)
{
	if (!hlist_unhashed(n)) {
		__hlist_del(n);
		INIT_HLIST_NODE(n);
	}
}

static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
{
	struct hlist_node *first = h->first;
	n->next = first;
	if (first) first->pprev = &n->next;
	h->first = n;
	n->pprev = &h->first;
#ifdef DBG_LIST
    n->my_hlist_head_at = h; h->list_len++;
#endif
}

/* next must be != 0 */
static inline void hlist_add_before(struct hlist_node *n, struct hlist_node *next)
{
	n->pprev = next->pprev;
	n->next = next;
	next->pprev = &n->next;
	*(n->pprev) = n;
#ifdef DBG_LIST
    n->my_hlist_head_at = next->my_hlist_head_at; next->my_hlist_head_at->list_len++;
#endif
}

static inline void hlist_add_behind(struct hlist_node *n, struct hlist_node *prev)
{
	n->next = prev->next;
	prev->next = n;
	n->pprev = &prev->next;
	if (n->next) n->next->pprev  = &n->next;
#ifdef DBG_LIST
    n->my_hlist_head_at = prev->my_hlist_head_at; prev->my_hlist_head_at->list_len++;
#endif
}

/* after that we'll appear to be on some hlist and hlist_del will work */
static inline void hlist_add_fake(struct hlist_node *n)
{
	n->pprev = &n->next;
}

static inline int hlist_fake(struct hlist_node *h)
{
	return h->pprev == &h->next;
}

/*
 * Check whether the node is the only node of the head without
 * accessing head:
 */
static inline int hlist_is_singular_node(struct hlist_node *n, struct hlist_head *h)
{
	return !n->next && n->pprev == &h->first;
}

/*
 * Move a list from one list head to another. Fixup the pprev
 * reference of the first entry if it exists.
 */
static inline void hlist_move_list(struct hlist_head *old, struct hlist_head *new_entry)
{
	new_entry->first = old->first;
	if (new_entry->first)
		new_entry->first->pprev = &new_entry->first;
	old->first = 0;
}

#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
#define hlist_for_each(pos, head) for (pos = (head)->first; pos ; pos = pos->next)
#define hlist_for_each_safe(pos, n, head) for (pos = (head)->first; pos && ({ n = pos->next; 1; }); pos = n)
#define hlist_entry_safe(ptr, type, member) ({ typeof(ptr) ____ptr = (ptr); ____ptr ? hlist_entry(____ptr, type, member) : 0; })

/**
 * hlist_for_each_entry	- iterate over list of given type
 * @pos:	the type * to use as a loop cursor.
 * @head:	the head for your list.
 * @member:	the name of the hlist_node within the struct.
 */
#define hlist_for_each_entry(pos, head, member) for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member); pos; pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))

/**
 * hlist_for_each_entry_continue - iterate over a hlist continuing after current point
 * @pos:	the type * to use as a loop cursor.
 * @member:	the name of the hlist_node within the struct.
 */
#define hlist_for_each_entry_continue(pos, member) for (pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member); pos; pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))

/**
 * hlist_for_each_entry_from - iterate over a hlist continuing from current point
 * @pos:	the type * to use as a loop cursor.
 * @member:	the name of the hlist_node within the struct.
 */
#define hlist_for_each_entry_from(pos, member) for (; pos; pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))

/**
 * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
 * @pos:	the type * to use as a loop cursor.
 * @n:		another &struct hlist_node to use as temporary storage
 * @head:	the head for your list.
 * @member:	the name of the hlist_node within the struct.
 */
#define hlist_for_each_entry_safe(pos, n, head, member) for (pos = hlist_entry_safe((head)->first, typeof(*pos), member); pos && ({ n = pos->member.next; 1; }); \ pos = hlist_entry_safe(n, typeof(*pos), member))

#endif
